from xml.sax import *
import re
import time

from core import processing as process
from core import objects 


class MRM_mzXML_Parser:
    
    def __init__(self,pathfile,time_cycle):
        self.handle=None
        self.xmlfile=pathfile
        self.time_cycle=time_cycle
        self.Spectra = []
        self.Chromato = []
                    
    def parsing(self):
        t= time.clock()
        self.handle = scanListHandler(self.time_cycle)
        parser = make_parser()
        parser.setContentHandler(self.handle)
        try:
            doc = file(self.xmlfile)
            print "Begin parsing..."
            t=time.clock()
            parser.parse(doc)
            doc.close()
            print time.clock()-t
        except (SAXException, IOError):
            return "Error in parsing the document"
        
                
        if not self.handle.scans:
            raise ValueError, "No scan detected"
        
        self.Spectra = process.Spectra_creation(self.handle.scans, self.handle.min_time, self.handle.max_time, self.handle.time_window)
        self.Chromato = process.Chromato_creation(self.handle.scans)
        print time.clock()-t
        
class scanListHandler(handler.ContentHandler):
    
    def __init__(self,time_window):
        self.scans = [] #scans lists
        self._isPrecursor=False #means MS else MS/MS
        self.max_time=None
        self.min_time=None
        self.scancount=None
        self.time_window=time_window

        

    
    def startElement(self, name, attrs):
        if name == 'scan':
            scan = objects.Scan({ \
                    'scanNumber':attrs.get('num',''), \
                    'msLevel': attrs.get('msLevel',''), \
                    'peaksCount': attrs.get('peaksCount',''), \
                    'scanType':attrs.get('scanType',''), \
                    'retentionTime': process.timeformat(attrs.get('retentionTime')), \
                    'basePeakMz':attrs.get('basePeakMz',''), \
                    'basePeakIntensity': attrs.get('basePeakIntensity',""), \
                    'precursorMz': '', \
                    'byteOrder': '', \
                    'compression': '', \
                    'precision': '',\
                    'pairOrder':'', \
                                })
            self.scans.append(scan)

        elif name == 'precursorMz':
            self._isPrecursor = True
            
        elif name=='msRun':
            self.min_time = process.timeformat(attrs.get('startTime',''))
            self.max_time = process.timeformat(attrs.get('endTime',''))
            self.scancount=attrs.get('scanCount','')
        """
        elif name=='peaks':
            self.scans[-1].Fields['byteOrder']=attrs.get('byteOrder','')
            self.scans[-1].Fields['compression']=attrs.get('compression','')
            self.scans[-1].Fields['precision']=attrs.get('precision','')
            self.scans[-1].Fields['pairOrder']=attrs.get('pairOrder','')
        """
            
    def endElement(self, name):
        if name == 'precursorMz':
            self._isPrecursor = False

            
    def characters(self, ch):
        prec=""
        if self._isPrecursor:
            prec+=ch
            self.scans[-1].Fields['precursorMz'] = int(prec)

  
                
    def RecupHeader(self,pathfile):
        f=open(pathfile,'r')
        line=f.readline()
        count=0
        #TODO: fix the regular expression
        #p= re.compile('*<scan *')
        #p=re.compile('\s+<scan\snum=\"\d+\"')
        #while not p.match(line):
        #while line !="*<scan num=\"1\"":
        while count < 16:
            line+=f.readline()
            count+=1
        return line
    
class stopParsing(Exception):
    pass


    #except: print "Error: wrong path"
def Main(pathfile,time_cycle):  
    xmlparser = mzXML_Parser(pathfile,time_cycle)
    xmlparser.Parsing()
    return xmlparser.handle
